// +-------------------------------- DISCLAIMER ---------------------------------+
// |                                                                             |
// | This program is provided to you free of charge "as such".                   |
// | You should not assume that this program is error-free or suitable for any   |
// | purpose whatsoever.                                                         |
// |                                                                             |
// | EURESYS does not give any representation, warranty or undertaking that this |
// | program is free of any defect or error or suitable for any purpose. EURESYS |
// | shall not be liable, in contract, in torts or otherwise, for any damages,   |
// | loss, costs, expenses or other claims for compensation, including those     |
// | asserted by third parties, arising out of or in connection with the use of  |
// | this program.                                                               |
// +-----------------------------------------------------------------------------+

#include "CameraHandler.h"
#include <chrono>
#include "Easy.h"

using namespace Euresys::Open_eVision;

CameraHandler::CameraHandler(): data_(nullptr), width_(0),
  height_(0), pitch_(0), image_(new EImageBW8()), abort_(false)
{}

CameraHandler::~CameraHandler()
{
  std::cout << "Close camera" << std::endl;
  if (cameraThread_.joinable())
  {
    abort_ = true;
    // waits for ProcessingThread::run to end
    cameraThread_.join();
  }
}

void CameraHandler::launchCamera()
{
  try
  {
    std::string imagePath = Easy::GetSampleImagesRootPath() + "EasyBarCode/Barcode 01 (EAN 13).tif";
    image_->Load(imagePath);
    width_ = image_->GetWidth();
    height_ = image_->GetHeight();
    pitch_ = image_->GetRowPitch();
    data_ = (uint8_t*)image_->GetImagePtr();

    // run main loop in a separate thread
    cameraThread_ = std::thread(&CameraHandler::run, this);
  }
  catch (EException e)
  {
    std::cerr << "failed to load image" << std::endl;
    abort_ = true;
  }
}

void CameraHandler::run()
{
  while(!abort_)
  {
    processImageMutex_.lock();
    // do nothing
    canProcessImage_.notify_one();
    processImageMutex_.unlock();
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }
}

void CameraHandler::stop()
{
  abort_ = true;
  canProcessImage_.notify_all();
}

void CameraHandler::getImage(EImageBW8 &image)
{
  std::unique_lock<std::mutex> lock(processImageMutex_);
  canProcessImage_.wait(lock);
  image.InitializeFromUnalignedBuffer(width_, height_, data_, pitch_);
}

bool CameraHandler::isAborted()
{
  return abort_;
}

